using Autofac;
using Autofac.Extensions.DependencyInjection;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Hosting;
using XfTechOAWeb.ApiServer.ServiceExtensions;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection;
using XfTechOAWeb.Dtos.AutoMapperConfig;
using XfTechOAWeb.Infrastructure.RedisCache;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Newtonsoft.Json;
using XfTechOAWeb.ApiServer.Auth;
using Microsoft.AspNetCore.Http;
using XfTechOAWeb.Infrastructure.Utilities;
using NLog.Web;
using XfTechOAWeb.Service.Background;
using XfTechOAWeb.Service.Hubs;
using XfTechOAWeb.ApiServer.Middlewares;

var builder = WebApplication.CreateBuilder(args);

//使用Autofac作为依赖注入的容器
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureContainer<ContainerBuilder>(builder =>
    {
        builder.RegisterModule(new AutofacServicesModuleReg()); //按模块注册模块
        builder.RegisterModule<AutofacPropertyModuleReg>();     
    });

//使用NLog作为日志记录器
builder.Host.UseNLog(); 

//注册控制器服务
builder.Services.AddControllers(options =>
{
    //options.Filters.Add<GlobalLogActionFilter>();       //全局行为过滤器
    //options.Filters.Add<GlobalExceptionFilter>();       //全局异常过滤器
    options.Filters.Add<PermissionAuthorizeFilter>();   //全局自定义权限过滤器
}).AddNewtonsoftJson(options => { //接口数据 json格式化配置
    // 忽略循环引用
    options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
    // 设置时间格式
    options.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
    // 不使用驼峰
    //options.SerializerSettings.ContractResolver = new DefaultContractResolver();
    // 如字段为null值，该字段不会返回到前端
    // options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
});

//注册身份验证和授权服务
builder.Services.AddAuthenticationSetup(builder.Configuration);
builder.Services.AddAuthorizationSetup();

//注册CSReids服务
builder.Services.AddCSRedisCache(builder.Configuration["RedisConnectionString"]);

//AutoMapper配置
builder.Services.AddAutoMapper(typeof(ModelToDtoMapperProfile));

//注册后台任务
//builder.Services.AddHostedService<MyHostedService>(); 
//swagger的配置
builder.Services.AddSwaggerSetup();

//用扩展方法封装类了Cors的配置
builder.Services.AddCorsSetup(builder.Configuration["CorsIps"].Split(','));

//用扩展方法封装类了Db的配置
builder.Services.AddDbSetup();

//使用 ServiceBasedControllerActivator 替换 DefaultControllerActivator；Controller 默认是由 Mvc 模块管理的，不在 Ioc 容器中。替换之后，将放在 Ioc 容器中。
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

builder.Services.AddHttpContextAccessor();

//注册SignalR，默认用json传输
builder.Services.AddSignalR();


#region 配置中间件管道
var app = builder.Build();

//配置HttpContext帮助类
AppHttpContext.Configure(app.Services.GetRequiredService<IHttpContextAccessor>());

if (app.Environment.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
    app.UseSwagger();
    app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "XfTechOAWeb v1"));
}

//静态文件中间件 文件必须在wwwroot根目录下
app.UseStaticFiles();

app.UseRouting();

app.UseCors("跨域策略1");     //配置跨域中间件

app.UseAuthentication();    //身份认证中间件(验证你是谁？）

app.UseAuthorization();     //授权中间件（验证你能干什么？）

app.UseMiddleware<LogMSGMiddleware>(); //自己日志中间件

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers(); //控制器里面是专注于我们业务系统的业务功能，其他的事情交给 过滤器、中间件
});

//开启路由节点 用来映射Signalr请求路径
app.MapHub<MessageHub>("/chathub");

#endregion

app.Run();
